package com.study.spaoplog;

import com.google.common.base.Stopwatch;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author MI
 * @version 1.0
 * @date 2021/6/4 22:34
 * <p>Java高并发编程详解p242 ConcurrentLinkedQueue 内存泄漏 使用ConcurrentHashSet替代 </p>
 */
public class ConcurrentLinkedQueueMemleak2 {
    public static void main(String[] args) throws InterruptedException {
        final ConcurrentLinkedQueue<MyBean> queue = new ConcurrentLinkedQueue<>();
        final MyBean myBean = new MyBean(1024 * 1024);
        queue.add(myBean);//这一行会导致内存泄漏
        int loop = 0;
        final MyBean myBeans = new MyBean(1024 * 1024);
        //方便打开JDK诊断工具，观察内存前后变化
        TimeUnit.SECONDS.sleep(10);
        final Stopwatch watch = Stopwatch.createStarted();
        while (true) {
            //每10_000 进行一次耗时统计并且输出
            if (loop % 10_000 == 0 && loop != 0) {
                final long elapsed = watch.stop().elapsed(TimeUnit.MICROSECONDS);
                System.out.printf("loop=%d duration=%d MS\n", loop, elapsed);
                watch.reset().start();
            }
            queue.add(myBeans);
            queue.remove(myBeans);
            ++loop;
        }
    }

    public static class MyBean {
        private final byte[] bytes;

        public MyBean(int bytes) {
            this.bytes = new byte[bytes];
        }
    }
}
